package orm

import (
	"database/sql"
	"fmt"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 实体对象属性名大写开头，数据表自动转为小写开头;
type Product struct {
	// 继承 gorm中的 Model
	gorm.Model
	Code  string
	Price uint
	// autoCreateTime | autoUpdateTime 自动插入时间戳
	Version time.Time `gorm:"autoCreateTime"`
}

var db *gorm.DB

func init() {
	dsn := "root:root@tcp(localhost:3306)/go_db?charset=utf8mb4&parseTime=true"
	db1, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}
	db = db1
}

func main_7() {
	var product Product

	// 创建外键表
	db.AutoMigrate(&User{}, &Company{})

	// createTable()
	// create()
	// selectOne(&product)
	// selectAll()
	// update(&product)

	fmt.Printf("product: %v\n", product)
	// del(&product)
}

// https://pkg.go.dev/gorm.io/gorm/callbacks
// https://gorm.io/docs/hooks.html
// BeforeCreate creates: 钩子函数
/**
BeforeSave
BeforeUpdate
AfterUpdate
AfterSave

BeforeCreate
AfterCreate
BeforeDelete
AfterDelete
*/
func (product *Product) BeforeCreate(db *gorm.DB) (err error) {
	fmt.Printf("插入操作之前......")
	return
}

// 删除
func del(product *Product) {
	// Delete - delete product
	db.Delete(&product, 1)
}

// 更新
func update(product *Product) {

	// Update - update product's price to 200
	db.Model(&product).Update("Price", 200)
	// Update - update multiple fields
	db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // non-zero fields
	// 使用 map 参数进行更新
	db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

}

// 查询
func selectOne(product *Product) {
	// Read
	// db.First(&product, 2)                 // find product with integer primary key
	// db.First(&product, "code = ?", "F42") // find product with code D42

	// 等价于 db.Where().Find()
	//  db.Where().First()

	// 匿名参数
	db.Where("code = @mycode", sql.Named("mycode", "F42")).Find(&product)

	// Select("p.code as code , p.price as price")
	// Select("code , price")
	db.Table("products as p").Where("code = ? and id = ?", "F42", 2).Select("p.code as code , p.price as price").Find(&product)

}

func selectAll() {
	// 查询所有数据
	var products []Product
	db.Find(&products)
	fmt.Printf("products: %v\n", products)
}

// 新增
func create() {
	// Create
	db.Create(&Product{Code: "D44", Price: 101})
}

// 创建表
func createTable() {
	// 创建数据库表
	db.AutoMigrate(&Product{})
}

// 实体之间外键关联
type User struct {
	Name      string
	Age       string
	Company   Company `gorm:"foreignKey:CompanyID"` // 指定外键
	CompanyID int
}

type Company struct {
	ID   int
	Name string
}

/**

mysql> show create table  users;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                                                               |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| users | CREATE TABLE `users` (
  `name` longtext COLLATE utf8mb4_unicode_ci,
  `age` longtext COLLATE utf8mb4_unicode_ci,
  `company_id` bigint DEFAULT NULL,
  KEY `fk_users_company` (`company_id`),
  CONSTRAINT `fk_users_company` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
+-------+------

*/
